#include "StdAfx.h"
#include "Exception.h"
#include "CppException.h"

CPPException::CPPException(LPEXCEPTION_POINTERS pException) {
	std::stringstream strm;

	strm << "A C++ exception was thrown by the program: " << std::endl;
	static const std::type_info& stdInfo = typeid(std::exception);

	LPBYTE pBaseObj = (LPBYTE)pException->ExceptionRecord->ExceptionInformation[1];
	_CatchableTypeArray* types = ((_ThrowInfo*)pException->ExceptionRecord->ExceptionInformation[2])->pCatchableTypeArray;
	bool typeFound = false;
	for(ui32 i = 0; i < types->nCatchableTypes; ++i) {
		_CatchableType& type = *(types->arrayOfCatchableTypes[i]);
		std::type_info* tinfo = (std::type_info*)type.pType;

		if(tinfo != NULL && (*tinfo) == stdInfo) {
			typeFound = true;
			std::exception* stdEx = (std::exception*)(pBaseObj + type.thisDisplacement.mdisp);
			strm << "Type: " << ((std::type_info*)(types->arrayOfCatchableTypes[0]->pType))->name() << " (derived from std::exception)" << std::endl;
			strm << "Message: " << stdEx->what();
		}
	}

	if(typeFound == false) {
		strm << "Type: " << ((std::type_info*)(types->arrayOfCatchableTypes[0]->pType))->name() << std::endl;
	}

	mMessage = strm.str().c_str();
}